<!--
 ՞˶･֊･˶՞ಣ Author       : Charlie
 ՞˶･֊･˶՞ಣ Date         : 2024-11-13 00:19:13
 ՞˶･֊･˶՞ಣ LastEditors  : Charlie
 ՞˶･֊･˶՞ಣ LastEditTime : 2024-12-01 17:32:22
 ՞˶･֊･˶՞ಣ Description  : 打印组件
-->
<template>
  <div class="pageIndex">
    <div class="topBtnBox">
      <div class="paper">
        <!-- 纸张大小 A3、A4 等 -->
        <!-- <template> -->
        <button
          v-for="(value, type) in paperSize"
          :key="type"
          @click="setPaper(type, value)"
        >
          {{ type }}
        </button>
        <!-- </template> -->
        <!-- 自定义纸张 -->
        <button @click="paperPopVisible = !paperPopVisible">自定义纸张</button>
        <!-- 自定义纸张 popover -->
        <div class="popover">
          <div class="popover-content" v-show="paperPopVisible">
            <!-- <div style="font-size: 16px; font-weight: bold">
              设置纸张宽高(mm)
            </div> -->
            <div>
              <input
                class="input"
                v-model="paperWidth"
                type="number"
                placeholder="宽(mm)"
              />
              <span>x</span>
              <input
                class="input"
                v-model="paperHeight"
                type="number"
                placeholder="高(mm)"
              />
            </div>
            <button @click.stop="setPaperOther">确定</button>
          </div>
        </div>
        <button @click="changeScale('+')">+</button>
        <button @click="changeScale('-')">-</button>
        <input
          v-model="scaleValue"
          disabled
          style="width: 40px; text-align: center"
        />
        <button @click="changeScale('=')">还原</button>
        <button @click="changeRotate()">旋转</button>
        <button @click="addPaper()">添加</button>
      </div>
      <div class="settingBtn">
        <button @click="backFn">返回</button>
        <!-- <button @click="previewHtmlFn">HTML预览</button> -->
        <button @click="toPdfFn">PDF预览</button>
        <button @click="previewFn">浏览器打印</button>
        <button @click="getJsonFn">查看JSON</button>
        <button @click="resetFn">清空</button>
        <button @click="saveFn" class="buttonOne">保存</button>
      </div>
    </div>
    <div class="bottomBox">
      <!-- 样式完全自定义 -->
      <div class="elementBox">
        <div class="title">基础元素</div>
        <!-- tid 与 defaultElementTypeProvider 中对应 -->
        <!-- 包含 class="ep-draggable-item" -->
        <div class="ep-draggable-item item" tid="defaultModule.text">
          <span>文本</span>
        </div>
        <div class="ep-draggable-item item" tid="defaultModule.image">
          <span>图片</span>
        </div>
        <div class="ep-draggable-item item" tid="defaultModule.longText">
          <span>长文本</span>
        </div>
        <div class="ep-draggable-item item" tid="defaultModule.table">
          <span>表格</span>
        </div>
        <div class="title">辅助</div>

        <div class="ep-draggable-item item" tid="defaultModule.hline">
          <span>横线</span>
        </div>
        <div class="ep-draggable-item item" tid="defaultModule.vline">
          <span>竖线</span>
        </div>
        <div class="ep-draggable-item item" tid="defaultModule.rect">
          <span>矩形</span>
        </div>
        <div class="ep-draggable-item item" tid="defaultModule.table">
          <span>表格</span>
        </div>
        <!-- </el-row> -->
      </div>
      <div class="designBox">
        <!-- 设计器的 容器 -->
        <div id="hiprint-printTemplate"></div>
      </div>
      <div class="settingBox">
        <!-- 元素参数的 容器 -->
        <div id="PrintElementOptionSetting"></div>
      </div>
    </div>
  </div>
</template>

<script>
// 局部引入
import { hiprint, defaultElementTypeProvider } from 'vue-plugin-hiprint'

export default {
  name: 'printIndex',
  props: {
    item: Object,
  },
  data() {
    return {
      //内置的几种页面大小
      paperSize: {
        // A1: { width: 841, height: 594 },
        A2: { width: 420, height: 594 },
        // A3: { width: 420, height: 297 },
        A4: { width: 210, height: 297 },
        A5: { width: 210, height: 148 },
        A6: { width: 105, height: 148 },
        // A7: { width: 105, height: 74 },
        A8: { width: 52, height: 74 },
        // B1: { width: 1000, height: 707 },
        B2: { width: 500, height: 707 },
        // B3: { width: 500, height: 353 },
        B4: { width: 250, height: 353 },
        B5: { width: 250, height: 176 },
        B6: { width: 125, height: 176 },
        // B7: { width: 125, height: 88 },
        B8: { width: 62, height: 88 },
      },
      hiprintTemplate: null,
      paperPopVisible: false,
      paperWidth: null,
      paperHeight: null,
      scaleValue: '100%',
    }
  },
  mounted() {
    // 初始化 provider
    hiprint.init({
      providers: [defaultElementTypeProvider()],
    })
    /**
     * 这里必须要在 onMounted 中去构建 左侧可拖拽元素 或者 设计器
     * 因为都是把元素挂载到对应容器中, 必须要先找到该容器
     */
    this.buildLeftElement()
    this.buildDesigner()
    if (this.item && this.item.json) {
      // 模板回显
      this.hiprintTemplate.update(this.item.json)
    }
  },
  methods: {
    /**
     * 构建左侧可拖拽元素
     * 注意: 可拖拽元素必须在 hiprint.init() 之后调用
     * 而且 必须包含 class="ep-draggable-item" 否则无法拖拽进设计器
     */
    buildLeftElement() {
      // eslint-disable-next-line no-undef
      hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'))
    },
    /**
     * 构建设计器
     * 注意: 必须要在 onMounted 中去构建
     * 因为都是把元素挂载到对应容器中, 必须要先找到该容器
     */
    buildDesigner() {
      // let hiprintTemplate
      // eslint-disable-next-line no-undef
      $('#hiprint-printTemplate').empty() // 先清空, 避免重复构建
      this.hiprintTemplate = new hiprint.PrintTemplate({
        settingContainer: '#PrintElementOptionSetting', // 元素参数容器
      })
      // 构建 并填充到 容器中
      this.hiprintTemplate.design('#hiprint-printTemplate')
    },
    // 设置纸张大小
    setPaper(type, value) {
      this.hiprintTemplate.setPaper(type, value)
    },
    setPaperOther() {
      if (this.paperWidth && this.paperHeight) {
        this.hiprintTemplate.setPaper(this.paperWidth, this.paperHeight)
        this.paperWidth = null
        this.paperHeight = null
        this.paperPopVisible = false
      }
    },
    backFn() {
      this.$parent.isEdit = false
    },
    // 保存模板
    saveFn() {
      const re = this.hiprintTemplate.getJson()
      this.$emit('getJson', re)
      this.backFn()
    },
    // 清空页面
    resetFn() {
      this.hiprintTemplate.clear()
    },
    // 查看JSON
    getJsonFn() {
      const re = this.hiprintTemplate.getJson()
      alert(JSON.stringify(re.panels[0]))
    },
    previewFn(json) {
      if (json) {
        this.hiprintTemplate.update(json)
      }
      // 需要填入的数据
      // this.hiprintTemplate.print(re, {}, {})
      this.hiprintTemplate.print()
    },
    // previewHtmlFn() {
    //   const re = this.hiprintTemplate.getJson()
    //   this.hiprintTemplate.getHtml(re)
    // },
    toPdfFn() {
      const re = this.hiprintTemplate.getJson()
      // scale为PDF清晰度，越高文件越大，浏览器约卡
      // isDownload true为直接下载，false为先打开新的窗口预览
      // type：''、'arraybuffer'、'dataurl'、'bloburl'、'dataurlstring'、'pdfobjectnewwindow'
      this.hiprintTemplate
        .toPdf(re, '模板', {
          scale: 2,
          isDownload: false,
          type: 'pdfobjectnewwindow',
        })
        .then()
    },
    changeScale(val) {
      let temp = this.scaleValue.substring(0, this.scaleValue.length - 1)
      let newVal = Number(temp) * 0.01
      if (val === '+') {
        // this.
        newVal = newVal + 0.1
      } else if (val === '-') {
        if (newVal === 0.1) return
        newVal = newVal - 0.1
      } else {
        newVal = 1
      }
      this.scaleValue = (newVal * 100).toFixed(0) + '%'
      // 这里的scaleValue是小数形式，如100%为1，50%为0.5
      this.hiprintTemplate.zoom(newVal)
      // 示例 缩小到54%
      // this.hiprintTemplate.zoom(0.54)
    },
    changeRotate() {
      // 旋转页面方向，将页面宽度高度互换。因此只有横纵两种情况，纵为默认方向
      this.hiprintTemplate.rotatePaper()
    },
    addPaper() {
      this.hiprintTemplate.addPrintPanel({
        width: 100,
        height: 130,
        paperFooter: 340,
        paperHeader: 10,
      })
    },
  },
}
</script>
<style lang="scss" scoped>
.topBtnBox {
  height: 60px;
  display: flex;
  justify-content: space-between;

  button {
    margin-right: 5px;
    // color: #dda0dd;
    // background-color: #fff;
    @include bottomOne;
    border: none;
    height: 30px;
    padding: 0 10px;
    border-radius: 5px;

    &.buttonOne {
      @include bottomTwo;
    }
  }

  .paper {
    display: flex;

    input {
      width: 80px;
      height: 30px;
      border: none;
      border-radius: 5px;
      padding: 0 3px;
      margin: 0 5px;
    }

    .popover {
      .popover-content {
        display: flex;
      }
    }
  }
}

.bottomBox {
  display: flex;
  justify-content: space-between;

  .elementBox {
    width: 240px;

    .ep-draggable-item {
      display: inline-block;

      span {
        display: block;
        width: 80px;
        height: 40px;
        line-height: 40px;
        margin: 0 10px 10px 0;
        border-radius: 5px;
        text-align: center;
        // color: "#dda0dd";
        // color: #fff;
        // background-color: #dda0dd;
        @include bottomTwo;
      }
    }
  }

  .settingBox {
    width: 360px;
  }

  .designBox {
    flex: 1;
  }
}
</style>
